<!--
 * @Author: boyyang
 * @Date: 2022-02-03 09:28:30
 * @LastEditTime: 2022-02-19 22:23:09
 * @LastEditors: boyyang
 * @Description: 
 * @FilePath: \boyyang\src\views\chatRoom\index.vue
-->

<!-- TODO: 修改组件嵌套 使用组件插槽 -->
<template>
    <background :url="userInfo?.avatarUrl">
        <div class="chat-room">
            <div class="chat-room-wrapper">
                <chat-room-left
                    :group-lists="groupLists"
                    :avatarUrl="userInfo?.avatarUrl"
                    @itemClick="itemClick"
                    @exit="exit"
                    @changeType="changeType"
                ></chat-room-left>
                <chat-room-right
                    :groupMes="groupMes"
                    :messageList="messageList"
                    :is-clear="isClear"
                    @submit="submit"
                    @onChange="onChange"
                    @iconClick="iconClick"
                ></chat-room-right>
                <sys-message
                    v-model:is-show="isShowSys"
                    :sysMessageList="sysMessageList"
                    @agreeReject="agreeReject"
                    @clearMessage="clearMessage"
                ></sys-message>
            </div>
            <group-members></group-members>
        </div>
    </background>
</template>

<script lang="ts" setup>
import chatRoomLeft from './components/chatRoomLeft.vue'
import chatRoomRight from './components/chatRoomRight.vue'
import groupMembers from './components/groupMembers.vue'
import { userMes, app } from '@/cloudbase'
import { tim, TIM } from '@/cloudIM'
import { env } from '@/utils/env'
import { useMessage } from '@/components/message'
import { router } from '@/router'
import SysMessage from './components/sysMessage.vue'
import { useLoading } from '@/components/fullScreenLoading'

const message = useMessage()
const loading = useLoading()
const userInfo = userMes()

const groupLists = ref<any[]>()
const groupId = ref<string>()
const groupMes = ref<any>() //群聊详细
const messageList = ref<any[]>()
const sysMessageList = ref<any[]>() //系统消息列表
const isShowSys = ref<boolean>(false) //系统消息弹框
const isClear = ref<boolean>(false)
const messageType = ref<string>('GROUP')
const timer = ref<any>()

onMounted(() => {
    initChatRoom()
})

// 发送文本消息
const submit = async (e: string) => {
    let _message = tim.createTextMessage({
        to: groupId.value,
        // TIM.TYPES.CONV_GROUP
        conversationType: TIM.TYPES.CONV_GROUP,
        // 消息优先级，用于群聊（v2.4.2起支持）。如果某个群的消息超过了频率限制，后台会优先下发高优先级的消息，详细请参考：https://cloud.tencent.com/document/product/269/3663#.E6.B6.88.E6.81.AF.E4.BC.98.E5.85.88.E7.BA.A7.E4.B8.8E.E9.A2.91.E7.8E.87.E6.8E.A7.E5.88.B6)
        // 支持的枚举值：TIM.TYPES.MSG_PRIORITY_HIGH, TIM.TYPES.MSG_PRIORITY_NORMAL（默认）, TIM.TYPES.MSG_PRIORITY_LOW, TIM.TYPES.MSG_PRIORITY_LOWEST
        // priority: TIM.TYPES.MSG_PRIORITY_NORMAL,
        payload: {
            text: e
        }
    })


    tim.sendMessage(_message).then((res: any) => {
        message.success('信息发送成功！')
        isClear.value = true
        timer.value && clearTimeout(timer.value)
        timer.value = setTimeout(() => {
            isClear.value = false
        }, 500)
    })

}

// 初始化
const initChatRoom = async () => {
    loading.start()
    let res = await app.callFunction({
        name: 'usersSig',
        data: {
            userId: userInfo?.uid,
            appId: env.VITE_APP_IMSDK_APPID,
            secretKey: env.VITE_APP_IMSDK_SECRETKEY
        }
    })

    let userID = userInfo?.uid
    let sig = res.result.sig

    tim.login({ userID: userID, userSig: sig }).then((loginStatus: any) => {
        // 登录成功
        tim.on(TIM.EVENT.SDK_READY, isReady)
        loading.end()
        message.success("群聊初始化成功~~")
    })
}

const isReady = async (isReadyStatus: any) => {
    tim.off(TIM.EVENT.SDK_READY, isReady)
    // 修改个人标配资料
    await tim.updateMyProfile({
        nick: userInfo?.nickName,
        avatar: userInfo?.avatarUrl,
        gender: TIM.TYPES.GENDER_MALE,
        selfSignature: '我的个性签名',
        allowType: TIM.TYPES.ALLOW_TYPE_ALLOW_ANY
    })

    getGroupsList()
}

// 获取消息列表
const getList = async () => {
    tim.off(TIM.EVENT.GROUP_LIST_UPDATED, getList)

    let res = await tim.getMessageList({ conversationID: messageType.value + groupId.value, count: 10 })
    const nextReqMessageID = res.data.nextReqMessageID // 用于续拉，分页续拉时需传入该字段。
    const isCompleted = res.data.isCompleted // 表示是否已经拉完所有消息。
    messageList.value = res.data.messageList
    console.log(res)
    tim.on(TIM.EVENT.GROUP_LIST_UPDATED, getList)
}

// 获取系统消息列表
const getSysMesList = async () => {
    let res = await tim.getMessageList({ conversationID: '@TIM#SYSTEM', count: 10 })
    const nextReqMessageID = res.data.nextReqMessageID // 用于续拉，分页续拉时需传入该字段。
    const isCompleted = res.data.isCompleted // 表示是否已经拉完所有消息。
    sysMessageList.value = res.data.messageList
    console.log(res)
}

// 获取群列表
const getGroupsList = () => {
    tim.getGroupList().then((imResponse: any) => {
        if (imResponse.data.groupList.length == 0) {
            joinInDefaultGroup()
            return
        }
        groupLists.value = imResponse.data.groupList
        groupId.value = imResponse.data.groupList[0].groupID
        groupMes.value = imResponse.data.groupList[0]
        console.log(imResponse)
        getList()
        // tim.on(TIM.EVENT.GROUP_LIST_UPDATED, getList)
    })
}

// 列表点击
const itemClick = (id: string) => {
    groupId.value = id
    getList()
}

// 消息监听
const messageListen = () => {
    // 监听事件，例如：
    // tim.on(TIM.EVENT.SDK_READY, function (event: any) {
    //     // 收到离线消息和会话列表同步完毕通知，接入侧可以调用 sendMessage 等需要鉴权的接口
    //     // event.name - TIM.EVENT.SDK_READY
    // })

    // tim.on(TIM.EVENT.MESSAGE_RECEIVED, function (event: any) {
    //     // 收到推送的单聊、群聊、群提示、群系统通知的新消息，可通过遍历 event.data 获取消息列表数据并渲染到页面
    //     // event.name - TIM.EVENT.MESSAGE_RECEIVED
    //     // event.data - 存储 Message 对象的数组 - [Message]
    // })

    // tim.on(TIM.EVENT.MESSAGE_REVOKED, function (event: any) {
    //     // 收到消息被撤回的通知
    //     // event.name - TIM.EVENT.MESSAGE_REVOKED
    //     // event.data - 存储 Message 对象的数组 - [Message] - 每个 Message 对象的 isRevoked 属性值为 true
    // })

    // tim.on(TIM.EVENT.MESSAGE_READ_BY_PEER, function (event: any) {
    //     // SDK 收到对端已读消息的通知，即已读回执。使用前需要将 SDK 版本升级至 v2.7.0 或以上。仅支持单聊会话。
    //     // event.name - TIM.EVENT.MESSAGE_READ_BY_PEER
    //     // event.data - event.data - 存储 Message 对象的数组 - [Message] - 每个 Message 对象的 isPeerRead 属性值为 true
    // })

    // tim.on(TIM.EVENT.CONVERSATION_LIST_UPDATED, function (event: any) {
    //     // 收到会话列表更新通知，可通过遍历 event.data 获取会话列表数据并渲染到页面
    //     // event.name - TIM.EVENT.CONVERSATION_LIST_UPDATED
    //     // event.data - 存储 Conversation 对象的数组 - [Conversation]
    // })


    // 收到群组列表更新通知，可通过遍历 event.data 获取群组列表数据并渲染到页面
    // event.name - TIM.EVENT.GROUP_LIST_UPDATED
    // event.data - 存储 Group 对象的数组 - [Group]
    // tim.on(TIM.EVENT.GROUP_LIST_UPDATED, getList)

    // tim.on(TIM.EVENT.PROFILE_UPDATED, function (event: any) {
    //     // 收到自己或好友的资料变更通知
    //     // event.name - TIM.EVENT.PROFILE_UPDATED
    //     // event.data - 存储 Profile 对象的数组 - [Profile]
    // })

    // tim.on(TIM.EVENT.BLACKLIST_UPDATED, function (event: any) {
    //     // 收到黑名单列表更新通知
    //     // event.name - TIM.EVENT.BLACKLIST_UPDATED
    //     // event.data - 存储 userID 的数组 - [userID]
    // })

    // tim.on(TIM.EVENT.ERROR, function (event: any) {
    //     // 收到 SDK 发生错误通知，可以获取错误码和错误信息
    //     // event.name - TIM.EVENT.ERROR
    //     // event.data.code - 错误码
    //     // event.data.message - 错误信息
    // })

    // tim.on(TIM.EVENT.SDK_NOT_READY, function (event: any) {
    //     // 收到 SDK 进入 not ready 状态通知，此时 SDK 无法正常工作
    //     // event.name - TIM.EVENT.SDK_NOT_READY
    // })

    // tim.on(TIM.EVENT.KICKED_OUT, function (event: any) {
    //     // 收到被踢下线通知
    //     // event.name - TIM.EVENT.KICKED_OUT
    //     // event.data.type - 被踢下线的原因，例如:
    //     //    - TIM.TYPES.KICKED_OUT_MULT_ACCOUNT 多实例登录被踢
    //     //    - TIM.TYPES.KICKED_OUT_MULT_DEVICE 多终端登录被踢
    //     //    - TIM.TYPES.KICKED_OUT_USERSIG_EXPIRED 签名过期被踢 （v2.4.0起支持）。 
    // })

    // tim.on(TIM.EVENT.NET_STATE_CHANGE, function (event: any) {
    //     //  网络状态发生改变（v2.5.0 起支持）。 
    //     // event.name - TIM.EVENT.NET_STATE_CHANGE 
    //     // event.data.state 当前网络状态，枚举值及说明如下： 
    //     //     \- TIM.TYPES.NET_STATE_CONNECTED - 已接入网络 
    //     //     \- TIM.TYPES.NET_STATE_CONNECTING - 连接中。很可能遇到网络抖动，SDK 在重试。接入侧可根据此状态提示“当前网络不稳定”或“连接中” 
    //     //    \- TIM.TYPES.NET_STATE_DISCONNECTED - 未接入网络。接入侧可根据此状态提示“当前网络不可用”。SDK 仍会继续重试，若用户网络恢复，SDK 会自动同步消息  
    // })
}

// 登出
const exit = () => {
    tim.off(TIM.EVENT.GROUP_LIST_UPDATED, getList)
    tim.logout()
    router.replace({
        name: 'Home'
    })

    message.success("退出群聊成功~~")
}

// 加入默认群
const joinInDefaultGroup = () => {
    tim.joinGroup({ groupID: '@TGS#24EKCRZH2', applyMessage: `${userInfo?.nickName}申请加入群聊`, type: TIM.TYPES.GRP_PUBLIC }).then((imResponse: any) => {
        console.log(imResponse)
        if (imResponse.data.status == 'WaitAdminApproval') {
            message.warning('正在等待管理员同意加入默认群聊')

            return
        }
        groupLists.value = [imResponse.data.group]
        groupId.value = imResponse.data.group.groupID


        getList()
    })
}

// 切换聊天类型
const changeType = (index: number) => {
    switch (index) {
        case 0:
            messageType.value = 'GROUP'
            getGroupsList()
            break
        case 1:
            break
        case 2:
            isShowSys.value = true
            getSysMesList()
            break
        default:
            return
    }

}

// 同意拒绝入群
const agreeReject = async (index: number, message: any) => {
    console.log(index)
    if (index == 0) {
        tim.handleGroupApplication({
            handleAction: 'Agree',
            handleMessage: '欢迎欢迎',
            message: message // 申请加群群系统通知的消息实例
        }).then(() => {
            isShowSys.value = false
            message.success('同意加入群聊')
        }).catch(() => {
            isShowSys.value = false
        })
    } else {
        tim.handleGroupApplication({
            handleAction: 'Reject',
            handleMessage: '不好意思',
            message: message // 申请加群群系统通知的消息实例
        }).then(() => {
            isShowSys.value = false
            message.error('拒绝加入群聊')
        }).catch(() => {
            isShowSys.value = false
        })

    }
}

// 清除系统消息
const clearMessage = async () => {
    tim.deleteConversation('@TIM#SYSTEM')
        .then(() => {
            isShowSys.value = false
            message.success('系统消息清除成功')
        })
        .catch(() => {
            isShowSys.value = false
            message.warning('没有更多系统消息')
        })


}

// 发送图片消息
const onChange = (e: any) => {
    loading.start()
    let file = e.file
    let _message = tim.createImageMessage({
        to: groupId.value,
        conversationType: TIM.TYPES.CONV_GROUP,
        // 消息优先级，用于群聊（v2.4.2起支持）。如果某个群的消息超过了频率限制，后台会优先下发高优先级的消息，详细请参考：https://cloud.tencent.com/document/product/269/3663#.E6.B6.88.E6.81.AF.E4.BC.98.E5.85.88.E7.BA.A7.E4.B8.8E.E9.A2.91.E7.8E.87.E6.8E.A7.E5.88.B6)
        // 支持的枚举值：TIM.TYPES.MSG_PRIORITY_HIGH, TIM.TYPES.MSG_PRIORITY_NORMAL（默认）, TIM.TYPES.MSG_PRIORITY_LOW, TIM.TYPES.MSG_PRIORITY_LOWEST
        // priority: TIM.TYPES.MSG_PRIORITY_NORMAL,
        payload: {
            file: file,
        },
        // 消息自定义数据（云端保存，会发送到对端，程序卸载重装后还能拉取到，v2.10.2起支持）
        // cloudCustomData: 'your cloud custom data'
        // onProgress: function (event) { console.log('file uploading:', event) }
    })

    tim.sendMessage(_message).then((res: any) => {
        message.success("消息发送成功")
        loading.end()
    })

}

// 
const iconClick = () => {
    tim.getGroupMemberList({ groupID: groupId.value }).then((res: any) => {
        console.log(res)
    })
}

</script>

<style scoped lang="scss">
.chat-room {
    box-sizing: border-box;
    width: 100vw;
    height: 100vh;
    // background-color: rgb(83, 156, 185);
    display: flex;
    justify-content: center;
    align-items: center;

    .chat-room-wrapper {
        width: 65%;
        height: 90%;
        background-color: #fff;
        box-shadow: 3px 5px 5px 3px rgba(0, 0, 0, 0.5);

        display: grid;
        grid-template-columns: 1.5fr 3fr;
    }
}

@media screen and (max-width: 1000px) {
    .chat-room {
        display: flex;
        align-items: start;
        .chat-room-wrapper {
            width: 100%;
            height: 100%;
            display: flex;
            align-items: start;
            flex-direction: column;
        }
    }
}
</style>
